#include<iostream>
void swap(int &a, int &b);
void swap(int *a, int *b);
int& test01();
int& test02();
void showNum(const int &a);

int main(){
// 内存分为四个区域：代码区、全局区、栈区、堆区。
// 全局区：全局变量、静态变量、常量
    // 常量中有字符串常量、const修饰的全局变量
// 栈区：函数的参数、局部变量
// 堆区：手动开辟和释放
    // 指针本质也是局部变量，指针保存的数据是放在堆区
    // int *p = new int(10);       //开辟一个值为10的空间
    // int *arr = new int[10];        //开辟一个长度为10的空数组
    // for(int i = 0; i < 10; i++){
    //     arr[i] = i;
    // }
    // printf("%d\n", *p);
    // for(int i = 0; i < 10; i++){
    //     printf("%d\n", arr[i]);
    // }
    // delete p;       //销毁p
    // delete[] arr;   //销毁数组arr
    
// 引用：给变量起别名
    // 语法：数据类型 &别名 = 原名
    // 引用必须初始化
    // 引用一旦初始化后不能更改

    // 引用作为函数参数
    // int a = 10, b = 20;
    // swap(a, b);
    // printf("%d %d\n",a,b);
    // swap(&a, &b);
    // printf("%d %d\n",a,b);

    // 引用做函数的返回值
    // 不要返回局部变量的引用
    // int &a = test01();
    // printf("%d\n",a);

    // 函数的调用可以做左值
    // int &a = test02();
    // printf("%d\n",a);
    // test02() = 1000;
    // printf("%d\n",a);

    // 引用的本质就是一个指针常量
    // int a = 10;
    // int * const ref1 = &a;
    // std::cout<< *ref1 << std::endl;
    // *ref1 = 20; 
    // std::cout<< *ref1 << std::endl;
    
    // int b = 30;
    // int &ref2 = b;
    // std::cout<< ref2 << std::endl;
    // ref2 = 40;
    // std::cout<< ref2 << std::endl;

    // 常量引用：用来修饰形参，防止误操作
    // int num = 10;
    // showNum(num);

    
    return 0;
}
void showNum(const int &a){
    std::cout<< a <<std::endl;
}
int& test01(){
    int a = 10;
    // printf("%d\n", a);
    return a;
}
int& test02(){
    static int a = 10;
    // printf("%d\n", a);
    return a;
}
void swap(int &a, int &b){
    int t = a;
    a = b;
    b = t;
}
void swap(int *a, int *b){
    int t = *a;
    *a = *b;
    *b = t;
}
